Material UI is a Material Design library made for React.
It’s a set of React components that have Material Design styles.
In this article, we’ll look at how to add popovers with Material UI.
Simple Popover
Popovers let us display some content over other things.
To add it, we can use the Popover
component.
For example, we can write:
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Popover from "@material-ui/core/Popover";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
const useStyles = makeStyles(theme => ({
typography: {
padding: theme.spacing(3)
}
}));
export default function App() {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
return (
<div>
<Button variant="contained" color="primary" onClick={handleClick}>
Open Popover
</Button>
<Popover
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "center"
}}
transformOrigin={{
vertical: "top",
horizontal: "center"
}}
>
<Typography className={classes.typography}>Popover content.</Typography>
</Popover>
</div>
);
}
to add a button to open the popover and the popover itself.
The anchorEl
prop has the anchor element of the popover, which is the button itself.
anchorOrigin
specifies where relative to the button do we display the popover.
transformOrigin
lets us change the position of the popover itself.
open
sets whether the popover ios open or not.
If the anchorEl
is set, then it’s open.
Otherwise, it’s not open.
onClose
is a function that runs when the popover closes.
Mouse Over Interaction
We can open a popover when we move our mouse over an element.
For example, we can write:
import React from "react";
import Popover from "@material-ui/core/Popover";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";
const useStyles = makeStyles(theme => ({
popover: {
pointerEvents: "none"
},
paper: {
padding: theme.spacing(3)
}
}));
export default function App() {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const handlePopoverOpen = event => {
setAnchorEl(event.currentTarget);
};
const handlePopoverClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
return (
<div>
<Typography
onMouseEnter={handlePopoverOpen}
onMouseLeave={handlePopoverClose}
>
Hover me
</Typography>
<Popover
className={classes.popover}
classes={{
paper: classes.paper
}}
open={open}
anchorEl={anchorEl}
anchorOrigin={{
vertical: "bottom",
horizontal: "left"
}}
transformOrigin={{
vertical: "top",
horizontal: "left"
}}
onClose={handlePopoverClose}
disableRestoreFocus
>
<Typography>some popover.</Typography>
</Popover>
</div>
);
}
We pass in functions to the onMouseEnter
prop to let us open the popover when we hover over the text.
Similarly, we pass in a function to the onMouseLeave
prop to close the modal when our mouse leaves the element respectively.
The other parts are the same as the previous example.
PopupState Helper
To make managing the popover state easier, we can use the material-ui-popup-state library to manage the state.
To install it, we run:
npm install --save material-ui-popup-state
Then we can write:
import React from "react";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import Button from "@material-ui/core/Button";
import Popover from "@material-ui/core/Popover";
import PopupState, { bindTrigger, bindPopover } from "material-ui-popup-state";
export default function App() {
return (
<PopupState variant="popover">
{popupState => (
<div>
<Button
variant="contained"
color="primary"
{...bindTrigger(popupState)}
>
Open Popover
</Button>
<Popover
{...bindPopover(popupState)}
anchorOrigin={{
vertical: "bottom",
horizontal: "center"
}}
transformOrigin={{
vertical: "top",
horizontal: "center"
}}
>
<Box p={3}>
<Typography>some popover.</Typography>
</Box>
</Popover>
</div>
)}
</PopupState>
);
}
We have the PopupState
coponent wirh the variant
set to popover
to display a popover.
Then inside it, we have a function that takes the popupState
parameter, which has the open state of the popover.
We use the bindTrigger
with it to return an object to toggle the popup in the button.
In the popover, we call bindPopover
to bind the open
prop to the popupState
.
The rest of the code is the same as previous examples.
Conclusion
We can add popovers with the Popover
component.
The material-ui-popup-state library can make managing the popover state easier.